home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Snippets / Stuart's Tech Notes / Sample AppleTalk adev / adev.c next >
Encoding:
C/C++ Source or Header  |  1996-03-29  |  5.2 KB  |  149 lines  |  [TEXT/KAHL]

  1. // Sample AppleTalk adev resource
  2. // (C) 1994-1996 Stuart Cheshire <cheshire@cs.stanford.edu>
  3. //
  4. // You need to contact Apple to get an adev id assigned.
  5. // This file must be compiled into a code resource of type 'adev' with your id.
  6. // This resource file is then merged into the final adev file built by the
  7. // atlk project (See atlk.c)
  8. // 
  9. // The main routine in assembly code here calls the three C routines below:
  10. // 1. doGetAdev indicates the available AppleTalk connection icons to display in
  11. // the Network Control Panel There is just one for the 'None' connection, but
  12. // other adevs may offer multiple connections -- eg. multiple serial ports --
  13. // in which case they are distinguished by an index in the low byte of d2
  14. // 2. doSelAdev is called when the user selects our icon
  15. // 3. doReSelAdev  is called when the user double-clicks on our icon
  16. // Some of the parameters to the C routines are declared volatile to provide
  17. // call-by-value-return semantics, to allow the C code to easily return values
  18. // in registers without having to use even more nasty inline assembly code.
  19. // If your compiler doesn't honour volatile parameters you'll have to write
  20. // inline assembly code.
  21. //
  22. // You should also read the "Macintosh AppleTalkĀ® Connections Programmer's Guide"
  23. // available from Apple.
  24.  
  25. #include <AppleTalk.h>
  26. #include "LAPEqu.h"
  27.  
  28. #include "StuTypes.h"
  29. #include "adev.h"
  30.  
  31. // *********************************************************************************
  32.  
  33. local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name);
  34. local void doSelAdev(u_long volatile pram, u_long const d2);
  35. local void doReSelAdev(u_long volatile pram, u_long const d2);
  36.  
  37. export void main(void)
  38.     {
  39.     asm        {
  40.     @0        move.l    a4, -(sp)        ; save A4
  41.             lea        @0, a4            ; set up global register
  42.             
  43.             cmpi.l    #GetADEV, D0    ; Is this a GetADEV call?
  44.             bne.s    @1                ; If not, try the next one
  45.             
  46.             move.l    a0, -(sp)        ; If yes,
  47.             move.l    d2, -(sp)        ; Push parameters on the stack
  48.             move.l    d1, -(sp)
  49.             bsr        doGetAdev        ; and make the call
  50.             move.l    (sp)+, d1
  51.             move.l    (sp)+, d2
  52.             move.l    (sp)+, a0
  53.             bra.s    @exit
  54.  
  55.     @1        cmpi.l    #SelectADEV, D0    ; Is this a SelectADEV call?
  56.             bne.s    @2                ; If not, try the next one
  57.  
  58.             move.l    d2, -(sp)        ; If yes,
  59.             move.l    d1, -(sp)        ; Push parameters on the stack
  60.             bsr        doSelAdev        ; and make the call
  61.             move.l    (sp)+, d1
  62.             move.l    (sp)+, d2
  63.             bra.s    @exit
  64.  
  65.     @2        cmpi.l    #ReSelADEV, D0    ; Is this a ReSelADEV call?
  66.             bne.s    @exit            ; If not, give up
  67.  
  68.             move.l    d2, -(sp)        ; If yes,
  69.             move.l    d1, -(sp)        ; Push parameters on the stack
  70.             bsr        doReSelAdev        ; and make the call
  71.             move.l    (sp)+, d1
  72.             move.l    (sp)+, d2
  73.  
  74.     @exit    move.l    (sp)+, a4        ; restore A4
  75.             }
  76.     }
  77.  
  78. // *********************************************************************************
  79.  
  80. local short GetMyResID(void)
  81.     {
  82.     short rID;
  83.     ResType rType;
  84.     Str255 rName;
  85.     GetResInfo(RecoverHandle((Ptr)&main), &rID, &rType, rName);
  86.     return(rID);
  87.     }
  88.  
  89. // *********************************************************************************
  90.  
  91. enum { InterfaceActive = -1, InterfaceInactive = 0, NoMoreInterfaces = 1 };
  92.  
  93. local u_short num_ports;
  94.  
  95. local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name)
  96.     {
  97.     // If d2 is zero, then this is the first adev call, and we should do any
  98.     // necessary initialization. As part of that initialization I set the high
  99.     // order bit of d2, so that on the next call I'll know that I've already done
  100.     // the initialization.
  101.     // The low byte (byte 0) of d2 contains a zero-based index to identify a
  102.     // particular port for adevs that support multiple ports (e.g. Printer Port
  103.     // and Modem Port) -- so we return index zero the first time and increment
  104.     // it on subsequent calls.
  105.     
  106.     if (d2)    d2++;            // If not first call, increment
  107.     else                    // else do any necessary one-time initialization
  108.         {
  109.         d2 = 0x80000000;    // Set the top bit
  110.         // Do initialization here,
  111.         // eg. count how many ports are available
  112.         num_ports = 1;
  113.         }
  114.  
  115.     // See if we have finished.
  116.     if ((d2 & 0xFF) >= num_ports) return(NoMoreInterfaces);
  117.  
  118.     // Now do any necessary per-port setup
  119.     
  120.     // Give the name of the port identified by index (d2 & 0xFF)
  121.     name = "\pNone";
  122.     
  123.     // Tell the control panel if this port is our currently selected one
  124.     if (((pram >> 8) & 0xFF) == (d2 & 0xFF)) return(InterfaceActive);
  125.     else return(InterfaceInactive);
  126.     }
  127.  
  128. // *********************************************************************************
  129.  
  130. // The system uses the least significant byte of the PRAM to store the ID of the adev
  131. // in use and the top three bytes are nominally free for us to use, although in practice
  132. // Duos seem to revert to LocalTalk on wake-up if the top word is not set to FFFF.
  133.  
  134. local void doSelAdev(u_long volatile pram, u_long const d2)
  135.     {
  136.     // User has clicked on one of our icons, identified by d2. Stash this code
  137.     // in the  AppleTalk PRAM so we'll know which port to open in the atlk resource.
  138.     pram = 0xFFFF0000 | (d2 << 8) | GetMyResID();
  139.     }
  140.  
  141. // *********************************************************************************
  142.  
  143. local void doReSelAdev(u_long volatile pram, u_long const d2)
  144.     {
  145.     // User has clicked again on our already selected icon
  146.     // Can display dialog for options or configuration display here.
  147.     pram = 0xFFFF0000 | (d2 << 8) | GetMyResID();
  148.     }
  149.